home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 with MFC / Programming Windows 95 with MFC (Microsoft Programming Series)(097-0001465)(1996).iso / NT / CODE / CHAP12 / BITMAPDEMO / BITMAPDEMO.CPP next >
C/C++ Source or Header  |  1996-04-05  |  8KB  |  292 lines

  1. //***********************************************************************
  2. //
  3. //  BitmapDemo.cpp
  4. //
  5. //***********************************************************************
  6.  
  7. #include <afxwin.h>
  8. #include "Resource.h"
  9. #include "BitmapDemo.h"
  10.  
  11. CMyApp myApp;
  12.  
  13. /////////////////////////////////////////////////////////////////////////
  14. // CMyApp member functions
  15.  
  16. BOOL CMyApp::InitInstance ()
  17. {
  18.     m_pMainWnd = new CMainWindow;
  19.     m_pMainWnd->ShowWindow (m_nCmdShow);
  20.     m_pMainWnd->UpdateWindow ();
  21.     return TRUE;
  22. }
  23.  
  24. /////////////////////////////////////////////////////////////////////////
  25. // CMainWindow message map and member functions
  26.  
  27. BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
  28.     ON_WM_CREATE ()
  29.     ON_WM_ERASEBKGND ()
  30.     ON_WM_PAINT ()
  31.     ON_WM_QUERYNEWPALETTE ()
  32.     ON_WM_PALETTECHANGED ()
  33.     ON_COMMAND (IDM_OPTIONS_DRAW_OPAQUE, OnOptionsDrawOpaque)
  34.     ON_COMMAND (IDM_OPTIONS_DRAW_TRANSPARENT, OnOptionsDrawTransparent)
  35.     ON_COMMAND (IDM_OPTIONS_EXIT, OnOptionsExit)
  36.     ON_UPDATE_COMMAND_UI (IDM_OPTIONS_DRAW_OPAQUE, OnUpdateDrawOpaqueUI)
  37.     ON_UPDATE_COMMAND_UI (IDM_OPTIONS_DRAW_TRANSPARENT,
  38.         OnUpdateDrawTransparentUI)
  39. END_MESSAGE_MAP ()
  40.  
  41. CMainWindow::CMainWindow ()
  42. {
  43.     m_bDrawOpaque = TRUE;
  44.     Create (NULL, "Bitmap Demo", WS_OVERLAPPEDWINDOW, rectDefault,
  45.         NULL, MAKEINTRESOURCE (IDR_MAINFRAME));
  46. }
  47.  
  48. int CMainWindow::OnCreate (LPCREATESTRUCT lpcs)
  49. {
  50.     if (CFrameWnd::OnCreate (lpcs) == -1)
  51.         return -1;
  52.  
  53.     m_bitmap.LoadBitmap (IDR_BITMAP);
  54.  
  55.     CClientDC dc (this);
  56.     if (dc.GetDeviceCaps (RASTERCAPS) & RC_PALETTE) {
  57.         struct {
  58.             LOGPALETTE lp;
  59.             PALETTEENTRY ape[63];
  60.         } pal;
  61.  
  62.         LOGPALETTE* pLP = (LOGPALETTE*) &pal;
  63.         pLP->palVersion = 0x300;
  64.         pLP->palNumEntries = 64;
  65.  
  66.         for (int i=0; i<64; i++) {
  67.             pLP->palPalEntry[i].peRed = 0;
  68.             pLP->palPalEntry[i].peGreen = 0;
  69.             pLP->palPalEntry[i].peBlue = 255 - (i * 4);
  70.             pLP->palPalEntry[i].peFlags = 0;
  71.         }
  72.         m_palette.CreatePalette (pLP);
  73.     }
  74.     return 0;
  75. }
  76.  
  77. BOOL CMainWindow::OnEraseBkgnd (CDC* pDC)
  78. {
  79.     CRect rect;
  80.     GetClientRect (&rect);
  81.  
  82.     CPalette* pOldPalette;
  83.     if ((HPALETTE) m_palette != NULL) {
  84.         pOldPalette = pDC->SelectPalette (&m_palette, FALSE);
  85.         pDC->RealizePalette ();
  86.     }
  87.  
  88.     DoGradientFill (pDC, &rect);
  89.  
  90.     if ((HPALETTE) m_palette != NULL)
  91.         pDC->SelectPalette (pOldPalette, FALSE);
  92.     return TRUE;
  93. }
  94.  
  95. void CMainWindow::OnPaint ()
  96. {
  97.     CRect rect;
  98.     GetClientRect (&rect);
  99.     CPaintDC dc (this);
  100.  
  101.     BITMAP bm;
  102.     m_bitmap.GetObject (sizeof (BITMAP), &bm);
  103.     int cx = (rect.Width () / (bm.bmWidth + 8)) + 1;
  104.     int cy = (rect.Height () / (bm.bmHeight + 8)) + 1;
  105.  
  106.     int i, j, x, y;
  107.     for (i=0; i<cx; i++) {
  108.         for (j=0; j<cy; j++) {
  109.             x = 8 + (i * (bm.bmWidth + 8));
  110.             y = 8 + (j * (bm.bmHeight + 8));
  111.             if (m_bDrawOpaque)
  112.                 m_bitmap.Draw (&dc, x, y);
  113.             else
  114.                 m_bitmap.DrawTransparent (&dc, x, y, RGB (255, 0, 0));
  115.         }
  116.     }
  117. }
  118.  
  119. BOOL CMainWindow::OnQueryNewPalette ()
  120. {
  121.     if ((HPALETTE) m_palette == NULL)   // Shouldn't happen, but
  122.         return 0;                       // let's be sure
  123.  
  124.     CClientDC dc (this);
  125.     CPalette* pOldPalette = dc.SelectPalette (&m_palette, FALSE);
  126.  
  127.     UINT nCount;
  128.     if (nCount = dc.RealizePalette ())
  129.         Invalidate ();
  130.  
  131.     dc.SelectPalette (pOldPalette, FALSE);
  132.     return nCount;
  133. }
  134.  
  135. void CMainWindow::OnPaletteChanged (CWnd* pFocusWnd)
  136. {
  137.     if ((HPALETTE) m_palette == NULL)   // Shouldn't happen, but
  138.         return;                         // let's be sure
  139.  
  140.     if (pFocusWnd != this) {
  141.         CClientDC dc (this);
  142.         CPalette* pOldPalette = dc.SelectPalette (&m_palette, FALSE);
  143.         if (dc.RealizePalette ())
  144.             Invalidate ();
  145.         dc.SelectPalette (pOldPalette, FALSE);
  146.     }
  147. }
  148.  
  149. void CMainWindow::DoGradientFill (CDC* pDC, CRect* pRect)
  150. {
  151.     CBrush* pBrush[64];
  152.     for (int i=0; i<64; i++)
  153.         pBrush[i] = new CBrush (PALETTERGB (0, 0, 255 - (i * 4)));
  154.  
  155.     int nWidth = pRect->Width ();
  156.     int nHeight = pRect->Height ();
  157.     CRect rect;
  158.  
  159.     for (i=0; i<nHeight; i++) {
  160.         rect.SetRect (0, i, nWidth, i + 1);
  161.         pDC->FillRect (&rect, pBrush[(i * 63) / nHeight]);
  162.     }
  163.  
  164.     for (i=0; i<64; i++)
  165.         delete pBrush[i];
  166. }
  167.  
  168. void CMainWindow::OnOptionsDrawOpaque ()
  169. {
  170.     m_bDrawOpaque = TRUE;
  171.     Invalidate ();
  172. }
  173.  
  174. void CMainWindow::OnOptionsDrawTransparent ()
  175. {
  176.     m_bDrawOpaque = FALSE;
  177.     Invalidate ();
  178. }
  179.  
  180. void CMainWindow::OnOptionsExit ()
  181. {
  182.     SendMessage (WM_CLOSE, 0, 0);
  183. }
  184.  
  185. void CMainWindow::OnUpdateDrawOpaqueUI (CCmdUI* pCmdUI)
  186. {
  187.     pCmdUI->SetCheck (m_bDrawOpaque ? 1 : 0);
  188. }
  189.  
  190. void CMainWindow::OnUpdateDrawTransparentUI (CCmdUI* pCmdUI)
  191. {
  192.     pCmdUI->SetCheck (m_bDrawOpaque ? 0 : 1);
  193. }
  194.  
  195. /////////////////////////////////////////////////////////////////////////
  196. // CMaskedBitmap member functions
  197.  
  198. void CMaskedBitmap::Draw (CDC* pDC, int x, int y)
  199. {
  200.     BITMAP bm;
  201.     GetObject (sizeof (BITMAP), &bm);
  202.     CPoint size (bm.bmWidth, bm.bmHeight);
  203.     pDC->DPtoLP (&size);
  204.  
  205.     CPoint org (0, 0);
  206.     pDC->DPtoLP (&org);
  207.  
  208.     CDC dcMem;
  209.     dcMem.CreateCompatibleDC (pDC);
  210.     CBitmap* pOldBitmap = dcMem.SelectObject (this);
  211.     dcMem.SetMapMode (pDC->GetMapMode ());
  212.  
  213.     pDC->BitBlt (x, y, size.x, size.y, &dcMem, org.x, org.y, SRCCOPY);
  214.  
  215.     dcMem.SelectObject (pOldBitmap);
  216. }
  217.  
  218. void CMaskedBitmap::DrawTransparent (CDC* pDC, int x, int y,
  219.     COLORREF crColor)
  220. {
  221.     BITMAP bm;
  222.     GetObject (sizeof (BITMAP), &bm);
  223.     CPoint size (bm.bmWidth, bm.bmHeight);
  224.     pDC->DPtoLP (&size);
  225.  
  226.     CPoint org (0, 0);
  227.     pDC->DPtoLP (&org);
  228.  
  229.     // Create a memory DC (dcImage) and select the bitmap into it
  230.     CDC dcImage;
  231.     dcImage.CreateCompatibleDC (pDC);
  232.     CBitmap* pOldBitmapImage = dcImage.SelectObject (this);
  233.     dcImage.SetMapMode (pDC->GetMapMode ());
  234.  
  235.     // Create a second memory DC (dcAnd) and in it create an AND mask
  236.     CDC dcAnd;
  237.     dcAnd.CreateCompatibleDC (pDC);
  238.     dcAnd.SetMapMode (pDC->GetMapMode ());
  239.  
  240.     CBitmap bitmapAnd;
  241.     bitmapAnd.CreateBitmap (bm.bmWidth, bm.bmHeight, 1, 1, NULL);
  242.     CBitmap* pOldBitmapAnd = dcAnd.SelectObject (&bitmapAnd);
  243.  
  244.     dcImage.SetBkColor (crColor);
  245.     dcAnd.BitBlt (org.x, org.y, size.x, size.y, &dcImage, org.x, org.y,
  246.         SRCCOPY);
  247.  
  248.     // Create a third memory DC (dcXor) and in it create an XOR mask
  249.     CDC dcXor;
  250.     dcXor.CreateCompatibleDC (pDC);
  251.     dcXor.SetMapMode (pDC->GetMapMode ());
  252.  
  253.     CBitmap bitmapXor;
  254.     bitmapXor.CreateCompatibleBitmap (&dcImage, bm.bmWidth, bm.bmHeight);
  255.     CBitmap* pOldBitmapXor = dcXor.SelectObject (&bitmapXor);
  256.  
  257.     dcXor.BitBlt (org.x, org.y, size.x, size.y, &dcImage, org.x, org.y,
  258.         SRCCOPY);
  259.  
  260.     dcXor.BitBlt (org.x, org.y, size.x, size.y, &dcAnd, org.x, org.y,
  261.         0x220326);
  262.  
  263.     // Copy the pixels in the destination rectangle to a temporary
  264.     // memory DC (dcTemp)
  265.     CDC dcTemp;
  266.     dcTemp.CreateCompatibleDC (pDC);
  267.     dcTemp.SetMapMode (pDC->GetMapMode ());
  268.  
  269.     CBitmap bitmapTemp;
  270.     bitmapTemp.CreateCompatibleBitmap (&dcImage, bm.bmWidth, bm.bmHeight);
  271.     CBitmap* pOldBitmapTemp = dcTemp.SelectObject (&bitmapTemp);
  272.  
  273.     dcTemp.BitBlt (org.x, org.y, size.x, size.y, pDC, x, y, SRCCOPY);
  274.  
  275.     // Generate the final image by applying the AND and XOR masks to
  276.     // the image in the temporary memory DC
  277.     dcTemp.BitBlt (org.x, org.y, size.x, size.y, &dcAnd, org.x, org.y,
  278.         SRCAND);
  279.  
  280.     dcTemp.BitBlt (org.x, org.y, size.x, size.y, &dcXor, org.x, org.y,
  281.         SRCINVERT);
  282.  
  283.     // Blit the resulting image to the screen
  284.     pDC->BitBlt (x, y, size.x, size.y, &dcTemp, org.x, org.y, SRCCOPY);
  285.  
  286.     // Restore the default bitmaps
  287.     dcTemp.SelectObject (pOldBitmapTemp);
  288.     dcXor.SelectObject (pOldBitmapXor);
  289.     dcAnd.SelectObject (pOldBitmapAnd);
  290.     dcImage.SelectObject (pOldBitmapImage);
  291. }
  292.